﻿using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class USWindow : EditorWindow
{
    private static USSequencer currentSequencer;
    private Transform edittingTransform;
    private Texture helpIcon;
    private bool isArmed;
    public Vector2 minWindowSize = new Vector2(500f, 100f);
    public static GameObject newSequencerPrefab;
    public static float previousTime;
    private bool settingsFolded;

    public static void CreateAndAttachObserver(USSequencer sequence)
    {
        foreach (USTimelineContainer container in sequence.TimelineContainers)
        {
            foreach (USTimelineBase base2 in container.Timelines)
            {
                if (base2 is USTimelineObserver)
                {
                    return;
                }
            }
        }
        Camera camera = null;
        Camera[] cameraArray = UnityEngine.Object.FindObjectsOfType(typeof(Camera)) as Camera[];
        foreach (Camera camera2 in cameraArray)
        {
            if (camera2.tag == "MainCamera")
            {
                camera = camera2;
            }
        }
        if (camera == null)
        {
            Debug.LogWarning("场景缺少MainCamera.");
        }
        GameObject obj2 = UnityEngine.Object.Instantiate(newSequencerPrefab) as GameObject;
        obj2.name = "Observer的时间线";
        obj2.transform.parent = sequence.transform;
        USTimelineContainer container2 = obj2.AddComponent(typeof(USTimelineContainer)) as USTimelineContainer;
        container2.Index = -1;
        GameObject obj3 = UnityEngine.Object.Instantiate(newSequencerPrefab) as GameObject;
        obj3.name = "Observer";
        obj3.transform.parent = obj2.transform;
        obj3.AddComponent(typeof(USTimelineObserver));
    }

    private USRecordSequence GetOrSpawnRecorder()
    {
        USRecordSequence sequence = UnityEngine.Object.FindObjectOfType(typeof(USRecordSequence)) as USRecordSequence;
        if (sequence != null)
        {
            return sequence;
        }
        string path = "EmptyPrefab";
        GameObject original = Resources.Load(path, typeof(GameObject)) as GameObject;
        if (original == null)
        {
            Debug.LogError("不能加载EmptyPrefab，请检查资源文件夹是否存在此文件");
            return null;
        }
        GameObject obj3 = UnityEngine.Object.Instantiate(original) as GameObject;
        obj3.name = "Recording Object";
        USRecordSequence sequence2 = obj3.AddComponent<USRecordSequence>();
        sequence2.CapturePath = USPreferenceWindow.CapturePath;
        sequence2.CaptureFrameRate = USPreferenceWindow.CaptureFrameRate;
        sequence2.UpscaleAmount = USPreferenceWindow.UpscaleAmount;
        return sequence2;
    }

    private void OnDestroy()
    {
        USControl.StopProcessingAnimationMode();
        if (currentSequencer != null)
        {
            currentSequencer.Stop();
        }
    }

    private void OnDisable()
    {
        EditorEventObjectMap.Clean();
        EditorTimelineObjectMap.Clean();
        USControlTimelines.Clean();
    }

    private void OnEnable()
    {
        EditorApplication.update = (EditorApplication.CallbackFunction) Delegate.Combine(EditorApplication.update, new EditorApplication.CallbackFunction(this.SequenceUpdate));
        EditorApplication.playmodeStateChanged = (EditorApplication.CallbackFunction) Delegate.Combine(EditorApplication.playmodeStateChanged, new EditorApplication.CallbackFunction(this.PlaymodeStateChanged));
        USControl.OnLoad();
    }

    private void OnGUI()
    {
        if (newSequencerPrefab == null)
        {
            string path = "Sequence";
            newSequencerPrefab = Resources.Load(path, typeof(GameObject)) as GameObject;
            if (newSequencerPrefab == null)
            {
                Debug.Log("找不到预制件 " + path + "，请检查资源文件夹是否存在");
                return;
            }
        }
        if ((Selection.activeTransform != null) && (Selection.activeTransform.GetComponent<USSequencer>() != null))
        {
            this.edittingTransform = Selection.activeTransform;
        }
        if (((Selection.activeTransform != null) && (Selection.activeTransform.GetComponent<USTimelineContainer>() != null)) && (Selection.activeTransform.GetComponent<USTimelineContainer>().Sequence != null))
        {
            this.edittingTransform = Selection.activeTransform.GetComponent<USTimelineContainer>().Sequence.transform;
        }
        if (((Selection.activeTransform != null) && (Selection.activeTransform.GetComponent<USTimelineBase>() != null)) && (Selection.activeTransform.GetComponent<USTimelineBase>().Sequence != null))
        {
            this.edittingTransform = Selection.activeTransform.GetComponent<USTimelineBase>().Sequence.transform;
        }
        if (((Selection.activeTransform != null) && (Selection.activeTransform.GetComponent<USEventBase>() != null)) && (Selection.activeTransform.GetComponent<USEventBase>().Sequence != null))
        {
            this.edittingTransform = Selection.activeTransform.GetComponent<USEventBase>().Sequence.transform;
        }
        GUILayout.BeginHorizontal(new GUILayoutOption[0]);
        if (newSequencerPrefab != null)
        {
            GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.MinHeight(37f) };
            if (GUILayout.Button("创建新序列", options))
            {
                Undo.RegisterSceneUndo("创建新序列");
                GameObject obj2 = UnityEngine.Object.Instantiate(newSequencerPrefab) as GameObject;
                obj2.name = newSequencerPrefab.name;
                Selection.activeTransform = obj2.transform;
                USSequencer sequence = obj2.AddComponent<USSequencer>();
                sequence.Version = USUpgradePaths.CurrentVersionNumber;
                CreateAndAttachObserver(sequence);
            }
        }
        if (this.helpIcon == null)
        {
            this.helpIcon = Resources.Load("IconHelp", typeof(Texture)) as Texture;
        }
        if (this.helpIcon != null)
        {
            //GUILayoutOption[] optionArray2 = new GUILayoutOption[] { GUILayout.MaxWidth(this.helpIcon.width + 12f) };
            //if (GUILayout.Button(this.helpIcon, optionArray2))
            //{
            //    USWelcomeScreenWindow.OpenWindow(true);
            //}
        }
        GUILayout.EndHorizontal();
        string message = "在层级视图中选中一个序列或创建一个新序列.";
        if (this.edittingTransform == null)
        {
            EditorGUILayout.HelpBox(message, MessageType.Info, true);
        }
        else if (this.edittingTransform.GetComponent<USSequencer>() == null)
        {
            EditorGUILayout.HelpBox(message, MessageType.Info, true);
        }
        else
        {
            USSequencer component;
            if (currentSequencer == null)
            {
                component = this.edittingTransform.GetComponent<USSequencer>();
            }
            else
            {
                component = this.edittingTransform.GetComponent<USSequencer>();
            }
            if (!Application.isPlaying && (currentSequencer != component))
            {
                component.Stop();
                USControl.StopProcessingAnimationMode();
            }
            currentSequencer = component;
            Event current = Event.current;
            if ((current.type == EventType.DragUpdated) && !AnimationUtility.InAnimationMode())
            {
                DragAndDrop.visualMode = DragAndDropVisualMode.Link;
                current.Use();
            }
            if ((current.type == EventType.DragPerform) && !AnimationUtility.InAnimationMode())
            {
                foreach (UnityEngine.Object obj3 in DragAndDrop.objectReferences)
                {
                    GameObject obj4 = obj3 as GameObject;
                    if (obj4 != component.gameObject)
                    {
                        DragAndDrop.AcceptDrag();
                        foreach (USTimelineContainer container in currentSequencer.TimelineContainers)
                        {
                            if (container.AffectedObject == obj4.transform)
                            {
                                return;
                            }
                        }
                        Undo.RegisterSceneUndo("添加观察对象 : " + obj4.name);
                        currentSequencer.CreateNewTimelineContainer(obj4.transform);
                    }
                }
                current.Use();
            }
            this.UpdateHeader(current, component);
            this.UpdateTimeline(current, component);
            List<Transform> observedObjects = component.ObservedObjects;
            foreach (USTimelineContainer container2 in component.TimelineContainers)
            {
                if (!observedObjects.Contains(container2.AffectedObject))
                {
                    observedObjects.Add(container2.AffectedObject);
                    break;
                }
            }
            foreach (Transform transform in observedObjects)
            {
                USTimelineContainer container3 = null;
                foreach (USTimelineContainer container4 in component.TimelineContainers)
                {
                    if (container4.AffectedObject == transform)
                    {
                        container3 = container4;
                        break;
                    }
                }
                if (container3 == null)
                {
                    observedObjects.Remove(transform);
                    break;
                }
            }
        }
    }

    [UnityEditor.MenuItem("Window/资源编辑器")]
    private static void OpenUSequencer()
    {
        USLicenseAgreementWindow.OpenWindow();
    }

    public void PlaymodeStateChanged()
    {
        USControl.StopProcessingAnimationMode();
        this.isArmed = false;
    }

    private void SequenceUpdate()
    {
        base.Repaint();
        USSequencer[] sequencerArray = UnityEngine.Object.FindObjectsOfType(typeof(USSequencer)) as USSequencer[];
        foreach (USSequencer sequencer in sequencerArray)
        {
            USUpgradePaths.RunUpgradePaths(sequencer);
        }
        if (currentSequencer != null)
        {
            float realtimeSinceStartup = Time.realtimeSinceStartup;
            if (currentSequencer.IsPlaying && !Application.isPlaying)
            {
                float deltaTime = realtimeSinceStartup - previousTime;
                currentSequencer.UpdateSequencer(deltaTime);
            }
            previousTime = realtimeSinceStartup;
        }
    }

    private void UpdateHeader(Event evt, USSequencer sequencer)
    {
        this.settingsFolded = EditorGUILayout.Foldout(this.settingsFolded, " 设置");
        if (this.settingsFolded)
        {
            EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
            sequencer.name = EditorGUILayout.TextField("序列名称", sequencer.name, new GUILayoutOption[0]);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
            sequencer.Duration = EditorGUILayout.FloatField("序列长度 (秒)", sequencer.Duration, new GUILayoutOption[0]);
            sequencer.IsLopping = EditorGUILayout.Toggle("循环", sequencer.IsLopping, new GUILayoutOption[0]);
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
            GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.MaxWidth(300f) };
            sequencer.PlaybackRate = EditorGUILayout.Slider("回放速率", sequencer.PlaybackRate, sequencer.MinPlaybackRate, sequencer.MaxPlaybackRate, options);
            EditorGUILayout.EndHorizontal();
        }
    }

    private void UpdateSequencerTimelinePane(Event evt, USSequencer sequencer)
    {
        EditorGUILayout.Space();
        EditorGUILayout.BeginHorizontal(new GUILayoutOption[0]);
        GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.MaxWidth(60f) };
        GUILayout.Label("时间线", EditorStyles.boldLabel, options);
        GUILayoutOption[] optionArray2 = new GUILayoutOption[] { GUILayout.MaxWidth(100f) };
        if (GUILayout.Button(!USControl.ShowOnlyAnimated ? "显示全部" : "只显示序列", optionArray2))
        {
            USControl.ShowOnlyAnimated = !USControl.ShowOnlyAnimated;
        }
        Color color = GUI.color;
        if (AnimationUtility.InAnimationMode())
        {
            GUI.color = Color.red;
        }
        if (sequencer.IsPlaying)
        {
            if (GUILayout.Button("暂停", new GUILayoutOption[0]))
            {
                sequencer.Pause();
                if (this.isArmed && (this.GetOrSpawnRecorder() != null))
                {
                    this.GetOrSpawnRecorder().PauseRecording();
                }
            }
        }
        else if (GUILayout.Button("播放", new GUILayoutOption[0]))
        {
            Undo.RegisterUndo(sequencer, "播放");
            USControl.StartProcessingAnimationMode(sequencer);
            sequencer.Play();
            if (this.isArmed && (this.GetOrSpawnRecorder() != null))
            {
                USRecordSequence orSpawnRecorder = this.GetOrSpawnRecorder();
                orSpawnRecorder.StartRecording();
                orSpawnRecorder.CapturePath = USPreferenceWindow.CapturePath;
                orSpawnRecorder.CaptureFrameRate = USPreferenceWindow.CaptureFrameRate;
                orSpawnRecorder.UpscaleAmount = USPreferenceWindow.UpscaleAmount;
            }
        }
        if (GUILayout.Button("停止", new GUILayoutOption[0]))
        {
            Undo.RegisterUndo(sequencer, "停止");
            sequencer.Stop();
            USControl.StopProcessingAnimationMode();
            if (this.isArmed)
            {
                if (this.GetOrSpawnRecorder() != null)
                {
                    this.GetOrSpawnRecorder().StopRecording();
                }
                UnityEngine.Object.DestroyImmediate(this.GetOrSpawnRecorder().gameObject);
            }
            this.isArmed = false;
        }
        if (Application.isPlaying)
        {
            if (this.isArmed)
            {
                GUI.color = Color.red;
            }
            GUILayoutOption[] optionArray3 = new GUILayoutOption[] { GUILayout.Width(25f) };
            if (GUILayout.Button("R", optionArray3))
            {
                if (this.isArmed)
                {
                    UnityEngine.Object.DestroyImmediate(this.GetOrSpawnRecorder().gameObject);
                }
                this.isArmed = !this.isArmed;
                if (this.isArmed)
                {
                    this.GetOrSpawnRecorder();
                }
            }
        }
        GUI.color = color;
        EditorGUILayout.EndHorizontal();
        Rect passedArea = new Rect(0f, !this.settingsFolded ? 95f : 155f, base.position.width, base.position.height - (!this.settingsFolded ? 95f : 135f));
        USControl.OnGUI(base.position, passedArea, sequencer);
    }

    private void UpdateTimeline(Event evt, USSequencer sequencer)
    {
        this.UpdateSequencerTimelinePane(evt, sequencer);
    }
}

